package com.hd.trans.ui.activity;

import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.widget.NestedScrollView;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.hd.trans.R;
import com.hd.trans.TranslationInterior;
import com.hd.trans.common.Constants;
import com.hd.trans.db.DataBaseMgr;
import com.hd.trans.db.bean.HuDunLanguage;
import com.hd.trans.db.bean.TranslateRecord;
import com.hd.trans.framework.click.XClickUtil;
import com.hd.trans.framework.dialog.ConfirmDialog;
import com.hd.trans.framework.dialog.EditorDlg;
import com.hd.trans.framework.dialog.LanguageDialog;
import com.hd.trans.framework.dialog.LanguageDialogType;
import com.hd.trans.framework.dialog.ShareDialog;
import com.hd.trans.framework.languages.ShareResultAdapter;
import com.hd.trans.framework.tools.AppEvents;
import com.hd.trans.framework.tools.HuDunEvent;
import com.hd.trans.homefun.EventCode;
import com.hd.trans.limit4Use.LimitUseListener;
import com.hd.trans.network.PreferenceMgr;
import com.hd.trans.network.component.HdTranslateComponent2;
import com.hd.trans.network.component.TranslateCallback;
import com.hd.trans.share.EnShareFileType;
import com.hd.trans.share.ShareTextFileManager;
import com.hd.trans.ui.adapter.RecordVoiceAdapter;
import com.hd.trans.ui.base.LimitBaseActivity;
import com.hd.trans.ui.component.HdRecognitionComponent;
import com.hd.trans.ui.component.HdTtsDownloadComponent;
import com.hd.trans.ui.component.RecognitionCallBack;
import com.hd.trans.ui.component.TtsDownloadCallback;
import com.hd.trans.ui.model.HomeVoiceModel;
import com.hd.trans.ui.service.VoicePlayService;
import com.hd.trans.utils.FileUtils;
import com.hd.trans.utils.NotificationUtil;
import com.hd.trans.utils.StringUtils;
import com.hd.trans.utils.ToastUtils;
import com.hd.trans.utils.TrackerForTrans;
import com.hd.trans.widgets.VoicePlayView;
import com.hd.trans.widgets.VoiceRecordHeader;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;

public class VoiceHomeActivity extends LimitBaseActivity {

    private int xD,yD;
    private int sx,sy;
    private RelativeLayout.LayoutParams params;
    private boolean closePass;

    @Override
    protected int getLayoutId() {
        return R.layout.aty_homevoice;
    }

    private RelativeLayout rootView;
    private SmartRefreshLayout refreshLayout;
    private RecyclerView recyclerView;
    private LinearLayout tvTips;
    private TextView tvFrom;
    private TextView tvTo;
    private ImageView back;
    private ImageView exchange;
    private RelativeLayout end_relativelayout;
    private Chronometer time_chronometer;
    //    private VoiceLineView voiceWaveView;
    private TextView tvContentRecognition;
    private LinearLayout lyRecognition;
    private NestedScrollView scrollRecognition;
    private LinearLayout lyTipsRecognition;
    private TextView tvToast;


    private RelativeLayout leftButton;
    private RelativeLayout rightButton;
    private TextView btnLeft;
    private TextView btnRight;
    private TextView clearAll;
    private View leftBt,rightBt;

    private RecordVoiceAdapter mRecordAdapter;
    private VoicePlayService mPlayerImp;//播放器控制

    private HdRecognitionComponent mRecognitionComponent;//语音识别组件

    private HdTranslateComponent2 mTranslateComponent;//  文本翻译组件
    private HdTtsDownloadComponent mTtsComponent;//  TTS组件
    private VoicePlayView mCurVoicePlayView;//当前操作播放控件
    private ClipboardManager clipMgr;//粘贴板控制
    private HomeVoiceModel mDataModel;
    private ShareDialog shareDialog;
    private boolean allowClick = true;
    private long startTime = 0;
    boolean isReverse;

    public static void open(Context context, LimitUseListener listenner) {
        setLimitListener(listenner);
        Intent intent = new Intent(context, VoiceHomeActivity.class);
        context.startActivity(intent);
    }

    private void initView() {
        back = (ImageView) findViewById(R.id.back);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        rootView = findViewById(R.id.rootView);
        tvFrom = (TextView) findViewById(R.id.tv_from);
        tvTo = (TextView) findViewById(R.id.tv_to);
        exchange = (ImageView) findViewById(R.id.icon_exchange);
        refreshLayout = (SmartRefreshLayout) findViewById(R.id.refreshLayout);
        recyclerView = (RecyclerView) findViewById(R.id.rv_record);
        tvTips = (LinearLayout) findViewById(R.id.tv_tips);
        btnLeft = (TextView) findViewById(R.id.btn_left);
        btnRight = (TextView) findViewById(R.id.btn_right);
        end_relativelayout = findViewById(R.id.end_relativelayout);
        time_chronometer = findViewById(R.id.time_chronometer);
//        voiceWaveView = findViewById(R.id.voiceWaveView);
        tvContentRecognition = findViewById(R.id.tv_content_recognition);
        lyRecognition = findViewById(R.id.ly_recognition);
        scrollRecognition = findViewById(R.id.scroll_recognition);
        lyTipsRecognition = findViewById(R.id.ly_tips_recognition);
        tvToast = findViewById(R.id.tv_toast);
        clearAll = findViewById(R.id.clear_all);
        clearAll.setOnTouchListener(onTouchListener);
        params = (RelativeLayout.LayoutParams) clearAll.getLayoutParams();

        leftButton = (RelativeLayout) findViewById(R.id.left_button);
        rightButton = (RelativeLayout) findViewById(R.id.right_relativeLayout);
        leftBt = findViewById(R.id.left_bt);
        rightBt = findViewById(R.id.right_bt);

        leftBt.setOnClickListener(selectLanguager);
        rightBt.setOnClickListener(selectLanguager);
        exchange.setOnClickListener(selectLanguager);


        leftButton.setOnClickListener(voiceClick);
        rightButton.setOnClickListener(voiceClick);
        clearAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //清空内容
                TranslationInterior.getTrackerListener().click(TrackerForTrans.YYFY, TrackerForTrans.CLEAR_ALL);
                clearRecords();
            }
        });

        //结束语音按钮
        end_relativelayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!closePass)return;
//                executeRecognize(isReverse);
                //结束语音按钮   停止录制语音
                stopVoice();
                //隐藏录制语音布局
                lyRecognition.setVisibility(View.GONE);
                Log.i("LYC","onClick()->doTranslateRecord()");
                //没有声音3秒后停止录制语音的需求
                showLoadDialog();
                doTranslateRecord();
            }
        });
    }

    View.OnTouchListener onTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (v.getId() == R.id.clear_all) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:// 获取手指第一次接触屏幕
                        xD = sx = (int) event.getRawX();
                        yD = sy = (int) event.getRawY();
                        return false;
                    case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动对应的事件
                        int x = (int) event.getRawX();
                        int y = (int) event.getRawY();
                        // 获取手指移动的距离
                        int dx = x - sx;
                        int dy = y - sy;
                        // 得到imageView最开始的各顶点的坐标
                        //int l = linGift.getLeft();
                        //int r = linGift.getRight();
                        int t = clearAll.getTop();
                        //int b = linGift.getBottom();
                        // 更改imageView在窗体的位置
                        //linGift.layout(l, t + dy, r, b + dy);
                        if ((dy < 0 && t > 180) || (dy > 0 && params.bottomMargin - dy > 25)) {
                            params.topMargin = params.topMargin + dy;
                            params.bottomMargin = params.bottomMargin - dy;
                            clearAll.setLayoutParams(params);
                        }
                        // 获取移动后的位置
                        sx = (int) event.getRawX();
                        sy = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:// 手指离开屏幕对应事件
                        int xU = (int) event.getRawX();
                        int yU = (int) event.getRawY();
                        if (Math.abs(xD - xU) < 20 && Math.abs(yD - yU) < 20) {
                            return false;
                        }
                        break;
                }
            }
            return true;// 不会中断触摸事件的返回
        }
    };

    //选择语言的点击事件
    View.OnClickListener selectLanguager = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(XClickUtil.isFastDoubleClick(v,XClickUtil.INTERVAL_MILLIS)){
                return;
            }
            if(lyRecognition.getVisibility() == View.VISIBLE){
                return;
            }
            boolean isFromPage = true;
            int id = v.getId();
            if (id == R.id.left_bt) {
                isFromPage = true;
            } else if (id == R.id.right_bt) {
                isFromPage = false;
            } else if (id == R.id.icon_exchange) {
                showTranslateAnimation();
                return;
            }
            /*SelectLanguageDialog.newInstance(mDataModel.getLanguageFrom().getValue(), mDataModel.getLanguageTo().getValue(), isFromPage, true, false)
                    .setOnLanguageChangedListener((language, isFrom) -> {
                        if (isFrom) {
                            mDataModel.setLanguageFrom(language);
                        } else {
                            mDataModel.setLanguageTo(language);
                        }
                    }).show(getSupportFragmentManager(), "VoiceHomeActivity");*/

            LanguageDialog dialog = new LanguageDialog(
                    Objects.requireNonNull(mDataModel.getLanguageFrom().getValue()),
                    Objects.requireNonNull(mDataModel.getLanguageTo().getValue()),
                    isFromPage, LanguageDialogType.VOICE, LanguageDialogType.TO_VOICE);
            dialog.show(getSupportFragmentManager(),"LanguageDialog");
            dialog.setOnLanguageChangedListener((fromLanguage, toLanguage , selectedLanguage) -> {
                mDataModel.setLanguageFrom(fromLanguage);
                PreferenceMgr.getInstance().getTranslatePreference().saveVoiceFromLanguage(fromLanguage.getName());
                mDataModel.setLanguageTo(toLanguage);
                PreferenceMgr.getInstance().getTranslatePreference().saveVoiceToLanguage(toLanguage.getName());
            });
        }
    };
    //点击底部语音识别按钮
    View.OnClickListener voiceClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(allowClick){
                isReverse = (R.id.right_relativeLayout == v.getId());
                startVoice(isReverse);
            }
        }
    };

    private void startVoice(boolean isReverse) {
        requestAudioPermission(() -> {
            if (isLimit4Use(EventCode.VOICE_TRANSLATE)) {
                executeRecognize(isReverse);
            }
        });
    }

    /**
     * 互换语种动画
     */
    private void showTranslateAnimation() {
        if("自动检测".equals(mDataModel.getLanguageFrom().getValue().getName())){
            ToastUtils.showNormal(getResources().getString(R.string.tips_to_not_auto));
            return;
        }
        TranslateAnimation ta1 = new TranslateAnimation(0, leftBt.getWidth() + exchange.getWidth(), 0, 0);
        ta1.setDuration(600);
        ta1.setFillAfter(true);
        leftBt.startAnimation(ta1);
        leftBt.bringToFront();

        TranslateAnimation ta2 = new TranslateAnimation(0, -rightBt.getWidth()-exchange.getWidth(), 0, 0);
        ta2.setDuration(600);
        ta2.setFillAfter(true);
        rightBt.startAnimation(ta2);
        rightBt.bringToFront();

        ta1.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                HuDunLanguage fromTemp = mDataModel.getLanguageFrom().getValue();
                mDataModel.setLanguageFrom(mDataModel.getLanguageTo().getValue());
                mDataModel.setLanguageTo(fromTemp);
                animation.cancel();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        ta2.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                animation.cancel();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    private void stopVoice(){
        if(mRecognitionComponent!=null){
            mRecognitionComponent.stopRecognition();
        }
        if(mXHandler != null){
            mXHandler.removeCallbacks(voiceRunnable);
            mXHandler.postDelayed(voiceRunnable,1500);
            mXHandler.post(hideToastRunnable);
        }
    }

    private Runnable voiceRunnable = new Runnable() {
        @Override
        public void run() {
            allowClick = true;
        }
    };

    private void stopByCountDown(){
        cancelTimers();
        //停止语音识别
        stopVoice();
        lyRecognition.setVisibility(View.GONE);
        doTranslateRecord();
    }

    //根据事件码，回调是否拦截
    private boolean isLimit4Use(EventCode code) {
        return !intercept(code);
    }

    @Override
    protected void initViewsAndEvents(Bundle savedInstanceState) {
        initView();
        setThemeColor();
        initData();
    }


    private void initData() {
        clipMgr = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);

        mDataModel = new ViewModelProvider(this).get(HomeVoiceModel.class);

        mRecognitionComponent = new HdRecognitionComponent(this, true);
        getLifecycle().addObserver(mRecognitionComponent);

        mTranslateComponent = new HdTranslateComponent2(this);
        getLifecycle().addObserver(mTranslateComponent);

        mTtsComponent = new HdTtsDownloadComponent();
        getLifecycle().addObserver(mTtsComponent);

        /*
         *  监听页面数据变化(语言改变，状态改变)
         */
        mDataModel.getLanguageFrom().observe(this, huDunLanguage -> {
            if (huDunLanguage != null) {
                tvFrom.setText(huDunLanguage.getName());
                if (Constants.VOICE_RECOGNIZING != mDataModel.getVoicePageState().getValue()) {
                    btnLeft.setText(huDunLanguage.getShortName());
                }
            }

        });
        mDataModel.getLanguageTo().observe(this, huDunLanguage -> {
            if (huDunLanguage != null) {
                tvTo.setText(huDunLanguage.getName());
                if (Constants.VOICE_RECOGNIZING != mDataModel.getVoicePageState().getValue()) {
                    btnRight.setText(huDunLanguage.getShortName());
                }
            }
        });
        mDataModel.getVoicePageState().observe(this, this::pageStateChanged);

        String fromLangName = PreferenceMgr.getInstance().getTranslatePreference().getVoiceFromLanguage();
        String toLangName = PreferenceMgr.getInstance().getTranslatePreference().getVoiceToLanguage();

        mDataModel.setVoicePageState(Constants.VOICE_NORMAL);
        mDataModel.setLanguageFrom(DataBaseMgr.getInstance().getLanguageByName(fromLangName));
        mDataModel.setLanguageTo(DataBaseMgr.getInstance().getLanguageByName(toLangName));

        /**
         * 获取屏幕高度传入adapter
         * 此处不考虑底部导航高度，不考虑中途设置系统底部导航。
         */
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecordAdapter = new RecordVoiceAdapter(null);
        mRecordAdapter.setWindowHeight(dm.heightPixels);

        mRecordAdapter.setHasStableIds(true);
        mRecordAdapter.setAnimationEnable(true);
        mRecordAdapter.setFooterWithEmptyEnable(false);
        mRecordAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom);

        recyclerView.setAdapter(mRecordAdapter);

        //下拉清空
        refreshLayout.setOnRefreshListener(refreshLayout -> clearRecords());
        refreshLayout.setRefreshHeader(new VoiceRecordHeader(this));
        mRecordAdapter.setVoiceClickListener(new RecordVoiceAdapter.VoiceClickListener() {

            @Override
            public void onMenuEditClick(View view, int position) {//编辑
                //关闭朗读语音
                if (mPlayerImp.isPlaying()) {
                    mPlayerImp.stopPlay();
                    if(mCurVoicePlayView!=null)mCurVoicePlayView.stopPlay();
                }
                if (isLimit4Use(EventCode.VOICE_EDIT_TRANSLATED)) {
                    TranslateRecord item = mRecordAdapter.getItem(position);
                    EditorDlg.newInstance(item.getContentOrig())
                            .setOnInputChangedListener(value -> {
                                if (isLimit4Use(EventCode.VOICE_EDIT_TRANSLATED_CONFRIM)) {
                                    if (item != null) {
                                        item.setContentOrig(value);
                                        mRecordAdapter.notifyItemChanged(position);
                                        DataBaseMgr.getInstance().updateTranslateRecord(item);
                                        mTtsComponent.deleteTtsFile(item,true, new Observer<Boolean>() {
                                            @Override
                                            public void onSubscribe(Disposable d) {
                                            }

                                            @Override
                                            public void onNext(Boolean aBoolean) {
                                            }

                                            @Override
                                            public void onError(Throwable e) {
                                            }

                                            @Override
                                            public void onComplete() {
                                                executeTranslate(item, true);
                                            }
                                        });
                                    }
                                }
                            }).show(getSupportFragmentManager(), "editor_dlg");
                }
            }

            @Override
            public void onMenuCopyClick(View view, int position) {  //复制
                if (isLimit4Use(EventCode.VOICE_COPY_TRANSLATED)) {
                    TranslateRecord item = mRecordAdapter.getItem(position);
                    ClipData mClipData = ClipData.newPlainText("Label", item.getContentOrig() + "\r\n" + item.getContentTranslate());
                    clipMgr.setPrimaryClip(mClipData);
                    //Toast.makeText(VoiceHomeActivity.this, getResources().getString(R.string.copy_success_tips), Toast.LENGTH_SHORT).show();
                    ToastUtils.showNormal(getResources().getString(R.string.copy_success_tips));
                }
            }

            @Override
            public void onMenuShareClick(View view, int position) {  //分享
               /* mRecordAdapter.getItem(position).getContentTranslate();
                ShareUtil.shareText(getActivity(), , "");*/
                //关闭朗读语音
                if (mPlayerImp.isPlaying()) {
                    mPlayerImp.stopPlay();
                    if(mCurVoicePlayView!=null)mCurVoicePlayView.stopPlay();
                }
                if (isLimit4Use(EventCode.VOICE_SHARE_TRANSLATED)) {
                    shareFile(position);
                    //分享没做回调 该方法本应该在成功回调后调用
                }
            }

            @Override
            public void onMenuDeleteClick(View view, int position) {  //删除
                //关闭朗读语音
                if (mPlayerImp.isPlaying()) {
                    mPlayerImp.stopPlay();
                    if(mCurVoicePlayView!=null)mCurVoicePlayView.stopPlay();
                }
                if (isLimit4Use(EventCode.VOICE_DELETE_TRANSLATED)) {
                    deleteItem(view, position);
                }
            }

            //语音播放
            @Override
            public void onVoicePlayClick(View view, int position) {
                if (isLimit4Use(EventCode.VOICE_PLAY_TRANS)) {
                    executeTtsPlay((VoicePlayView) view, position);
                }
            }

            @Override
            public void onRetryClick(View view, int position) {
                //关闭朗读语音
                if (mPlayerImp.isPlaying()) {
                    mPlayerImp.stopPlay();
                    if(mCurVoicePlayView!=null)mCurVoicePlayView.stopPlay();
                }
                if (isLimit4Use(EventCode.VOICE_EDIT_TRANSLATED)) {
                    TranslateRecord item = mRecordAdapter.getItem(position);
                    executeTranslate(item, false);
                }
            }
        });

        NotificationUtil.getInstance().checkNotification(this);
    }

    private void shareFile(int mPosition) {
        final int newPosition = mPosition;
        shareDialog = ShareDialog.builder()
                .setButtonColor(TranslationInterior.getThemeColor())
                .setItemClickListenner(new ShareDialog.OnShareItemClickListenner() {
                    @Override
                    public void OnItemClick(Dialog dialog, ShareResultAdapter adapter, int position) {
                        if (shareMG == null) {
                            shareMG = new ShareTextFileManager(getActivity());
                        }
                        switch (position) {
                            case 0: //导出Word
                                if (isLimit4Use(EventCode.VOICE_SHARE_WORD)) {
                                    shareWord(newPosition);
                                }

                                break;
                            case 1://导出TXT
                                if (isLimit4Use(EventCode.VOICE_SHARE_TXT)) {
                                    shareTxt(newPosition);
                                }

                                break;
                            case 2://导出PDF
                                if (isLimit4Use(EventCode.VOICE_SHARE_PDF)) {
                                    sharePdf(newPosition);
                                }
                                break;
                        }
                        dialog.dismiss();
                    }
                }).build(false);
        shareDialog.show(getSupportFragmentManager(), "TextHomeActivity");
    }


    private ShareTextFileManager shareMG;

    private SimpleDateFormat mFormat;

    public String shareFileName() {
        if (null == mFormat)
            mFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
        return mFormat.format(new Date().getTime());
    }

    private void shareWord(int position) {
        shareMG.shareTextFile(StringUtils.template(mRecordAdapter.getItem(position).getContentOrig()
                , mRecordAdapter.getItem(position).getContentTranslate()), shareFileName() + ".doc", EnShareFileType.WORD_FILE);
    }

    private void shareTxt(int position) {
        shareMG.shareTextFile(StringUtils.template(mRecordAdapter.getItem(position).getContentOrig()
                , mRecordAdapter.getItem(position).getContentTranslate()), shareFileName(), EnShareFileType.TXT_FILE);
    }

    private void sharePdf(int position) {
        shareMG.shareTextFile(StringUtils.template(mRecordAdapter.getItem(position).getContentOrig()
                , mRecordAdapter.getItem(position).getContentTranslate()), shareFileName() + ".pdf", EnShareFileType.PDF_FILE);
    }

    //删除条目
    private void deleteItem(View view, int position) {
        ConfirmDialog.builder().setTitle("删除语音")
                .setContent("删除语音后将无法恢复，确定是否仍要删除该条语音?")
                .setRightListenner(new ConfirmDialog.OnComfrimDialogListenner() {
                    @Override
                    public void OnComfrim(Dialog dialog) {
                        TranslateRecord record = mRecordAdapter.getItem(position);
                        if (mPlayerImp.isPlaying()) {
                            mPlayerImp.stopPlay();
                        }
                        mTtsComponent.stopDownload(record);

                        mRecordAdapter.remove(position);

                        if (mRecordAdapter.getData().isEmpty()) {
                            mRecordAdapter.removeAllFooterView();
                            tvTips.setVisibility(View.VISIBLE);
                            clearAll.setVisibility(View.GONE);
                        }
                        mTtsComponent.deleteTtsFile(record, true, new Observer<Boolean>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                            }

                            @Override
                            public void onNext(Boolean aBoolean) {
                            }

                            @Override
                            public void onError(Throwable e) {
                            }

                            @Override
                            public void onComplete() {
                                DataBaseMgr.getInstance().deleteRecord(record);
                            }
                        });
                    }
                })
                .build().show(getSupportFragmentManager(), "voice_home_delete_item");
    }


    @Override
    protected void onStart() {
        super.onStart();
        //埋点
        TranslationInterior.getTrackerListener().view(TrackerForTrans.YYFY + TrackerForTrans.SY);
        // 绑定服务
        mPlayerImp = new VoicePlayService();
        refreshRecords();
    }

    @Override
    public void onBackPressed() {
        if(lyRecognition.getVisibility() == View.VISIBLE){
            end_relativelayout.performClick();
        }else {
            super.onBackPressed();
        }
    }

    @Override
    public void onPause() {
        if(lyRecognition.getVisibility() == View.VISIBLE){
            end_relativelayout.performClick();
        }
        if (mPlayerImp != null && mPlayerImp.isPlaying()) {
            mPlayerImp.stopPlay();
        }
        if (mCurVoicePlayView != null) {
            mCurVoicePlayView.stopPlay();
        }
        mCurVoicePlayView = null;
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        cancelTimers();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPlayerImp.release();
        mDataModel.getLanguageFrom().removeObservers(this);
        mDataModel.getLanguageTo().removeObservers(this);
        mDataModel.getVoicePageState().removeObservers(this);
        mRecognitionComponent.destroy();
        mTranslateComponent.destroy();
        mTtsComponent.destroy();
        getLifecycle().removeObserver(mTranslateComponent);
        getLifecycle().removeObserver(mRecognitionComponent);
        getLifecycle().removeObserver(mTtsComponent);
    }

    protected void setThemeColor() {
        leftButton.setBackgroundTintList(ColorStateList.valueOf(TranslationInterior.getThemeColor()));
        lyRecognition.setBackgroundTintList(ColorStateList.valueOf(TranslationInterior.getThemeColor()));
        rightButton.setBackgroundTintList(ColorStateList.valueOf(TranslationInterior.getThemeColor()));
    }

    private void cancelTimers() {
        if (mTimer != null) {
            mTimer.cancel();
        }
    }

    /**
     * 当前状态改变
     */
    private void pageStateChanged(int pageState) {

        switch (pageState) {
            case Constants.VOICE_NORMAL://
                tvContentRecognition.setText("");
//                voiceWaveView.stopWave();
                rightButton.setEnabled(true);
                leftButton.setEnabled(true);
                lyRecognition.setVisibility(View.GONE);
                refreshLayout.setEnabled(true);
                break;

            case Constants.VOICE_RECOGNIZING://识别中
                tvTips.setVisibility(View.GONE);
                rightButton.setEnabled(false);
                leftButton.setEnabled(false);
                lyRecognition.setVisibility(View.VISIBLE);
                refreshLayout.setEnabled(false);
                closePass = false;
                mXHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        closePass = true;
                    }
                },1000);
                break;

        }

    }


    /**
     * 刷新记录
     */
    private void refreshRecords() {
        Observable.create((ObservableOnSubscribe<List<TranslateRecord>>) emit -> {
            emit.onNext(DataBaseMgr.getInstance().getAllRecords(true));
            emit.onComplete();
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(bindToLifecycle())
                .subscribe(new DisposableObserver<List<TranslateRecord>>() {
                    @Override
                    public void onNext(List<TranslateRecord> list) {
                        Collections.reverse(list);
                        mRecordAdapter.setNewInstance(list);
                        if (list == null || list.isEmpty() || list.size() < 1) {
                            tvTips.setVisibility(View.VISIBLE);
                            clearAll.setVisibility(View.GONE);
                        } else {
                            tvTips.setVisibility(View.GONE);
                            clearAll.setVisibility(View.VISIBLE);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }


    private ConfirmDialog dialog;

    /**
     * 清空记录
     */
    private void clearRecords() {
        if (dialog == null) {
            dialog = ConfirmDialog.builder()
                    .setContent(getResources().getString(R.string.confirm_tip))
                    .rightTxtColor(TranslationInterior.getThemeColor())
                    .setRightListenner(new ConfirmDialog.OnComfrimDialogListenner() {
                        @Override
                        public void OnComfrim(Dialog dialog) {
                            //关闭朗读语音
                            if (mPlayerImp.isPlaying()) {
                                mPlayerImp.stopPlay();
                                if(mCurVoicePlayView!=null)mCurVoicePlayView.stopPlay();
                            }
                            List<TranslateRecord> records = mRecordAdapter.getData();
                            mRecordAdapter.setNewInstance(null);
                            mRecordAdapter.removeAllFooterView();
                            refreshLayout.finishRefresh();
                            tvTips.setVisibility(View.VISIBLE);
                            clearAll.setVisibility(View.GONE);
                            mTtsComponent.deleteAllTtsFiles(new Observer<Boolean>() {
                                @Override
                                public void onSubscribe(Disposable d) {
                                }

                                @Override
                                public void onNext(Boolean aBoolean) {

                                }

                                @Override
                                public void onError(Throwable e) {

                                }

                                @Override
                                public void onComplete() {
                                    DataBaseMgr.getInstance().deleteRecords(records);
                                }
                            });
                        }
                    })
                    .setLeftListenner(new ConfirmDialog.OnComfrimDialogListenner() {
                        @Override
                        public void OnComfrim(Dialog dialog) {
                            refreshLayout.finishRefresh(100, false);
                        }
                    })
                    .build();
        }
        dialog.show(getSupportFragmentManager(), "VoiceHomeActivity");
    }


    //无语音3秒后自动关闭是识别。。
    private CountDownTimer mTimer = new CountDownTimer(4000, 4000) {

        @Override
        public void onTick(long millisUntilFinished) {

        }

        //cancel后执行。
        @Override
        public void onFinish() {
            //停止语音识别
            stopByCountDown();
        }
    };

    /**
     * 语音识别
     * isReverse 是否为逆向翻译
     */
    private void executeRecognize(boolean isReverse) {
        mDataModel.setOperateLanguage(!isReverse ?
                mDataModel.getLanguageFrom().getValue() : mDataModel.getLanguageTo().getValue());

        if (mPlayerImp.isPlaying()) {
            mPlayerImp.stopPlay();
        }
        if (mCurVoicePlayView != null)
            mCurVoicePlayView.stopPlay();
        mCurVoicePlayView = null;


        //如果不在录音状态...
        if (Constants.VOICE_RECOGNIZING != mDataModel.getVoicePageState().getValue()) {
            mXHandler.postDelayed(showToastRunnable, 5000);
            allowClick = false;
            time_chronometer.setBase(SystemClock.elapsedRealtime());//计时器清零
            time_chronometer.start();
            end_relativelayout.setVisibility(View.VISIBLE);
            startTime = System.currentTimeMillis();
            //进入录音状态...
            mDataModel.setVoicePageState(Constants.VOICE_RECOGNIZING);
            scrollRecognition.postDelayed(() -> scrollRecognition.fullScroll(View.FOCUS_UP), 10);
            mRecognitionComponent.voiceRecognition(mDataModel.getOperateLanguage().getValue(), new RecognitionCallBack() {
                /**
                 * 失败回调  执行概率极低 无关紧要
                 * @param msg
                 * @param code
                 */
                @Override
                public void onRecognitionFailed(String msg, int code) {
                    startTime = 0;
                    stopVoice();
                    hideLoadDialog();
                    String origContent = tvContentRecognition.getText().toString();
                    mDataModel.setVoicePageState(Constants.VOICE_NORMAL);
//                    ToastUtils.showError(R.string.voice_service_busy);
                    Toast.makeText(VoiceHomeActivity.this, R.string.voice_service_busy, Toast.LENGTH_SHORT).show();
                    if (!TextUtils.isEmpty(origContent)) {
                        TranslateRecord record = new TranslateRecord();
                        record.setIsVoice(true);
                        record.setIsCollected(false);
                        record.setIsReverse(isReverse);
                        if(isReverse){
                            record.setLanguageFrom(mDataModel.getLanguageTo().getValue());
                            record.setLanguageTo(mDataModel.getLanguageFrom().getValue());
                        }else {
                            record.setLanguageFrom(mDataModel.getLanguageFrom().getValue());
                            record.setLanguageTo(mDataModel.getLanguageTo().getValue());
                        }
                        record.setContentOrig(origContent);
                        record.setTriggerTime(System.currentTimeMillis());
                        DataBaseMgr.getInstance().addTranslateRecord(record);
                        mRecordAdapter.addData(0, record);
                        recyclerView.scrollToPosition(0);
                        tvTips.setVisibility(View.GONE);
                        executeTranslate(record, false);
                    }
                }

                /**
                 * 该方法会在 调用停止方法后，执行。  即语音识别成功
                 * @param msg
                 * @param code
                 */
                @Override
                public void onRecognitionCompleted(String msg, int code) {
                    hideLoadDialog();
                    if (startTime > 0) {
                        consumeFreeTrialTime(System.currentTimeMillis() - startTime);
                        startTime = 0;
                    }
                }

                /**
                 *  该方法会在 每识别到文字会回调   也就是录制语音期间频繁回调
                 * @param msg
                 * @param code
                 * @param sentenceOver
                 * @param sentence
                 */
                @Override
                public void onRecognitionChanged(String msg, int code, boolean sentenceOver, String sentence) {
                    if (Constants.VOICE_RECOGNIZING == mDataModel.getVoicePageState().getValue()) {
                        //识别到文字，说明还在说话，取消掉3秒倒计时任务
                        mTimer.cancel();
                        //重新开启3秒不说话自动关闭倒计时
                        Log.i("LYC","onRecognitionChanged()->mTimer.start()");
                        mTimer.start();
                    }
                    Log.i("LYC","onRecognitionChanged()->msg="+msg+";sentence="+sentence);

                    //根据不断回调 把数据实时显示
                    if (Constants.VOICE_RECOGNIZING == mDataModel.getVoicePageState().getValue()) {
                        mXHandler.post(hideToastRunnable);
                        tvContentRecognition.setText(msg);
                        scrollRecognition.postDelayed(() -> scrollRecognition.fullScroll(View.FOCUS_DOWN), 10);
                    }
                }

                @Override
                public void onVoiceChanged(int waveBytes, int readBytes) {
                }
            });
        }
    }

    private void doTranslateRecord(){
        cancelTimers();
        String origContent = tvContentRecognition.getText().toString();
        mDataModel.setVoicePageState(Constants.VOICE_NORMAL);
        stopVoice();
        if (TextUtils.isEmpty(origContent)) {
            hideLoadDialog();
            if(mRecordAdapter.getData().isEmpty()){
                tvTips.setVisibility(View.VISIBLE);
            }
            Toast.makeText(VoiceHomeActivity.this, R.string.voice_tip_null, Toast.LENGTH_SHORT).show();
        } else {
            TranslateRecord record = new TranslateRecord();
            record.setIsVoice(true);
            record.setIsCollected(false);
            record.setIsReverse(isReverse);
            if(isReverse){
                record.setLanguageFrom(mDataModel.getLanguageTo().getValue());
                record.setLanguageTo(mDataModel.getLanguageFrom().getValue());
            }else {
                record.setLanguageFrom(mDataModel.getLanguageFrom().getValue());
                record.setLanguageTo(mDataModel.getLanguageTo().getValue());
            }
            record.setContentOrig(origContent);
            record.setTriggerTime(System.currentTimeMillis());
            DataBaseMgr.getInstance().addTranslateRecord(record);
            mRecordAdapter.addData(0, record);
            recyclerView.scrollToPosition(0);
            //翻译接口请求
            executeTranslate(record, false);
        }
    }

    private Runnable showToastRunnable = new Runnable() {
        @Override
        public void run() {
            tvToast.setVisibility(View.VISIBLE);
        }
    };

    private Runnable hideToastRunnable = new Runnable() {
        @Override
        public void run() {
            mXHandler.removeCallbacks(showToastRunnable);
            tvToast.setVisibility(View.GONE);
        }
    };

    //是否绑定eventbus
    @Override
    protected boolean isBindEventBusHere() {
        return true;
    }

    /**
     * eventbus 通知语音播放完成。
     *
     * @param event
     */
    @Override
    protected void onXEventRecv(HuDunEvent<?> event) {
        super.onXEventRecv(event);
        switch (event.getEventCode()) {
            case AppEvents.PLAY_COMPLETE: //播放器播放完成
                if (mCurVoicePlayView != null)
                    mCurVoicePlayView.stopPlay();
                mCurVoicePlayView = null;
                break;
        }
    }

    /**
     * 执行翻译
     */
    private void executeTranslate(TranslateRecord record, final boolean isEdit) {

        if (record == null || TextUtils.isEmpty(record.getContentOrig()))
            return;

        if(record.getLanguageTo() == null
                || record.getLanguageFrom() == null){
            return;
        }
        record.setTranslateState(Constants.VOICE_RECORD_TRANSLATING);
        int index = mRecordAdapter.getData().indexOf(record);
        if (index != -1) {
            mRecordAdapter.setData(index, record);
            clearAll.setVisibility(View.VISIBLE);
        }
        DataBaseMgr.getInstance().updateTranslateRecord(record);
        String fromTranslateCode = record.getLanguageFrom().getTranslateCode();
        String toTranslateCode = record.getLanguageTo().getTranslateCode();

        mTranslateComponent.translationText(
                this,
                record.getContentOrig(),
                fromTranslateCode,
                toTranslateCode,
                PreferenceMgr.getInstance().isOpenOfflineTrans(),
                new TranslateCallback() {
                    @Override
                    public void onTranslateFailed(int code, String msg) {
                        if(code == Constants.ResponseCode.ERROR_IS_DANGER
                                || code == Constants.ResponseCode.ERROR_COMM){
                            ToastUtils.showError(msg);
                        }else {
                            ToastUtils.showError(R.string.fanyi_faith_tip);
                        }
                        record.setTranslateState(Constants.VOICE_RECORD_FAILED);
                        int index = mRecordAdapter.getData().indexOf(record);
                        if (index != -1) {
                            mRecordAdapter.setData(index, record);
                        }
                        DataBaseMgr.getInstance().updateTranslateRecord(record);
                        hideLoadDialog();
                    }

                    @Override
                    public void onTranslateCompleted(
                            String data,
                            String fromLangCode,
                            String toLangCode,
                            boolean status) {
//                        int mIndex = mRecordAdapter.getData().indexOf(record);
                        record.setContentTranslate(data);
                        record.setTranslateState(Constants.VOICE_RECORD_NORMAL);
                        mRecordAdapter.notifyDataSetChanged();

                        DataBaseMgr instance = DataBaseMgr.getInstance();
                        instance.updateTranslateRecord(record);
                        //埋点
                        TranslationInterior.getTrackerListener().view(TrackerForTrans.YYFY + TrackerForTrans.JG);

                        hideLoadDialog();
                    }
                });
    }


    /**
     * 执行语音合成并播放
     */
    private void executeTtsPlay(VoicePlayView voicePlayView, int position) {
        if (voicePlayView == null || voicePlayView.isLoading()) {
            return;
        }
        TranslateRecord record = mRecordAdapter.getItem(position);

        //有时翻译会返回  ". "
        if (record == null
                || StringUtils.isEmpty(record.getContentTranslate())
                || record.getLanguageFrom() == null
                || record.getLanguageTo() == null)
            return;

        String wavTime = String.valueOf(record.getTriggerTime());
//        String content = record.getContentTranslate().trim();

        String ttsCode = record.getLanguageTo().getTtsCode();
        if (StringUtils.isEmpty(ttsCode)) {
            Toast.makeText(VoiceHomeActivity.this, "该语言暂不支持语音播放", Toast.LENGTH_SHORT).show();
            return;
        }
        if (mPlayerImp.isPlaying()) {
            mPlayerImp.stopPlay();
            if(mCurVoicePlayView != null && mCurVoicePlayView.isPlaying()){
                mCurVoicePlayView.stopPlay();
            }
            if(voicePlayView == mCurVoicePlayView){
                return ;
            }
        }
        if (voicePlayView.isPlaying()) {
            mCurVoicePlayView = voicePlayView;
            voicePlayView.stopPlay();
            return;
        }

        if (mCurVoicePlayView != null && mCurVoicePlayView.isPlaying()) {
            mCurVoicePlayView.stopPlay();
        }
        mCurVoicePlayView = voicePlayView;

        String itemWavPath = FileUtils.getWavFileAbsolutePath(String.format(Locale.getDefault(), "%s_%s_%02d.wav", "true", wavTime,
                PreferenceMgr.getInstance().getTranslatePreference().getVoiceSpeed()));

        File file = new File(itemWavPath);

        if (file.length() > 0) {
            voicePlayView.startPlay();
            mPlayerImp.startPlay(itemWavPath);
        } else {
            voicePlayView.loading();
            mTtsComponent.getTtsFile(record,true, itemWavPath, new TtsDownloadCallback() {
                @Override
                public void onCompleted() {
                    if (voicePlayView.equals(mCurVoicePlayView)) {
                        voicePlayView.startPlay();
                        mPlayerImp.startPlay(itemWavPath);
                    } else {
                        voicePlayView.stopPlay();
                    }
                }

                @Override
                public void onDownloadFailed(int code, String msg) {
                    Log.i("onDownloadFailed", msg);
                    if (voicePlayView == null) {
                        voicePlayView.loadingFailed();
                        Toast.makeText(VoiceHomeActivity.this, R.string.tips_voice_download_failed, Toast.LENGTH_SHORT).show();
                    } else {
                        voicePlayView.stopPlay();
                        Toast.makeText(VoiceHomeActivity.this, R.string.tips_voice_download_failed, Toast.LENGTH_SHORT).show();
                        /*if (voicePlayView.equals(mCurVoicePlayView)) {
                        }*/
                    }

                }

                @Override
                public void onMergeFailed(int code, String msg) {
                    Log.i("onMergeFailed", msg);
                    if (voicePlayView == null) {
                        voicePlayView.loadingFailed();
                        Toast.makeText(VoiceHomeActivity.this, R.string.tips_voice_play_failed, Toast.LENGTH_SHORT).show();
                    } else {
                        voicePlayView.stopPlay();
                        Toast.makeText(VoiceHomeActivity.this, R.string.tips_voice_play_failed, Toast.LENGTH_SHORT).show();
                        /*if (voicePlayView.equals(mCurVoicePlayView)) {
                        }*/
                    }
                }
            });
        }
    }

    @NonNull
    @Override
    public EventCode getPageType() {
        return EventCode.VOICE_TRANSLATE;
    }
}